<template>
  <div v-loading="loading" class="app-container">
    <div id="map" ref="map" style="width:100%;height:900px;" />
    <!-- <div class="colors">
      <dl v-for="(item,index) in colors" :key="index" class="flex">
        <dt :style="{background:item.color}">{{ item.value }}</dt>
      </dl>
    </div> -->
    <div class="tools">
      <el-button type="primary" class="mr12" @click="insertCircleWg">{{ btnTitle }}</el-button>
      <el-select v-model="awc" clearable filterable placeholder="AWC历史计算图层" class="mr12" style="width:200px">
        <el-option
          v-for="(item,index) in awcs"
          :key="index"
          :label="item.key"
          :value="item.data"
        />
      </el-select>
      <el-select v-model="nrct" clearable filterable placeholder="NRCT历史计算图层" style="width:400px">
        <el-option
          v-for="(item,index) in nrcts"
          :key="index"
          :label="item.key"
          :value="item.data"
        />
      </el-select>
    </div>
    <div v-if="layers.length > 0" class="btn-container">
      <el-button type="primary" size="medium" @click="drawFinish">完成绘制</el-button>
    </div>
  </div>
</template>

<script>

import * as turf from '@turf/turf'
import { mapGetters } from 'vuex'
import { colors, colorsGcwd } from '@/utils/constant'
import 'leaflet.pm'
import 'leaflet.pm/dist/leaflet.pm.css'
import mapConfig from '@/config/map'
import { getPoint, uniqueArr } from '@/utils'
import { fetch } from '@/api/statistics'
import { saveCells } from '@/api/field'
export default {
  name: 'UtilsCell',
  data() {
    return {
      loading: false,
      nrcts: [],
      awcs: [],
      btnTitle: '插入网格',
      map: {},
      urls: mapConfig.mapTypes[mapConfig.initType],
      awcLayer: null,
      awcLayerContent: null,
      nrctLayer: null,
      nrctLayerContent: null,
      show: false,
      colors,
      nrct: '',
      awc: '',
      circleGridLayer: null,
      squareGridLayer: null,
      layers: [],
      layer: [],
      latlngs: [],
      latlngsArr: []
    }
  },
  computed: {
    ...mapGetters(['project', 'fields']),
    field() {
      const idx = this.fields.findIndex((val) => {
        return +val.project_id === this.project.id
      })
      return this.fields[idx]
    },
    circlePolygon() {
      const center = [this.project.lng, this.project.lat]
      const radius = 0.1499
      const options = { steps: 100, units: 'kilometers', properties: { foo: 'bar' }}
      return turf.circle(center, radius, options)
    }
  },
  watch: {
    awc: {
      handler(newVal) {
        if (newVal && newVal.length > 0) {
          this.createAwcLayer()
        } else {
          this.removeAwcLayer()
        }
      },
      deep: true,
      immediate: true
    },
    nrct: {
      handler(newVal) {
        this.removeNrctLayer()
        if (newVal && newVal.length > 0) {
          this.loading = true
          setTimeout(() => {
            this.createNrctLayer()
          }, 1000)
        }
      },
      deep: true,
      immediate: true
    }
  },
  mounted() {
    this.initMap()
    this.fetch('nrct')
    this.fetch('awcs')
  },
  methods: {
    async saveCells(postData) {
      const { msg } = await saveCells(this.field.id, postData)
      this.$message.success(msg)
    },
    async fetch(type) {
      const { data } = await fetch(type)
      if (type === 'nrct') {
        this.nrcts = data
      } else {
        this.awcs = [{ key: 'awc', data }]
      }
    },
    insertCircleWg() {
      if (!this.circleGridLayer) {
        const circleLayers = []
        const distances = [30, 45.2, 64, 78.3, 90.5, 101.1, 110.8, 119.7, 127.9, 135.7, 143, 150]
        const angleUnit = 5
        for (let i = 0; i < 360 / 5; i++) {
          const angle = angleUnit * i
          const point = getPoint([this.project.lng, this.project.lat], 150, angle)
          const latlngs = [[this.project.lat, this.project.lng], point]
          // eslint-disable-next-line no-undef
          const polyline = L.polyline(latlngs, { color: '#409eff', weight: 2 }).addTo(this.map)
          // eslint-disable-next-line no-undef
          L.layerGroup(polyline).setZIndex(9999)
          circleLayers.push(polyline)
        }

        distances.forEach((val) => {
        // eslint-disable-next-line no-undef
          const polygon = new L.Circle([this.project.lat, this.project.lng], val, {
            color: '#409eff', // 颜色
            fillColor: '#fff',
            fillOpacity: 0, // 透明度
            weight: 2
          }).addTo(this.map)
          // this.map.addLayer(polygon)
          // eslint-disable-next-line no-undef
          L.layerGroup(polygon).setZIndex(9999)
          circleLayers.push(polygon)
        })
        this.circleGridLayer = circleLayers
        this.btnTitle = '移除网格'
      } else {
        this.circleGridLayer.forEach((item) => {
          this.map.removeLayer(item)
        })
        this.circleGridLayer = null
        this.btnTitle = '插入网格'
      }
    },
    insertWg() {
      if (!this.squareGridLayer) {
        this.btnTitle = '移除网格'
        var bbox = [114.9115, 37.4658, 114.9154, 37.4688]
        var cellSide = 0.01
        var options = { units: 'kilometers', weight: 2 }

        var squareGrid = turf.squareGrid(bbox, cellSide, options)
        // eslint-disable-next-line no-undef
        this.squareGridLayer = L.geoJson(squareGrid).addTo(this.map)
      } else {
        this.map.removeLayer(this.squareGridLayer)
        this.squareGridLayer = null
        this.btnTitle = '插入网格'
      }
    },
    showDialog() {
      this.$refs.mainForm.show()
    },
    initMap() {
      // eslint-disable-next-line no-undef
      var baseLayer = L.tileLayer(
        this.urls[0], {
          attribution: '...',
          maxZoom: 18
        })

      // eslint-disable-next-line no-undef
      const map = L.map('map', {
        center: [37.467294, 114.913504],
        zoom: 18,
        zoomControl: false,
        maxZoom: 18,
        attributionControl: false,
        layers: [baseLayer]
      })
      map.pm.setLang('zh')
      map.pm.addControls({
        position: 'topleft',
        drawPolygon: true, // 绘制多边形
        drawMarker: false, // 绘制标记点
        drawCircleMarker: false, // 绘制圆形标记
        drawPolyline: false, // 绘制线条
        drawRectangle: true,	// 绘制矩形
        drawCircle: false, // 绘制圆圈
        editMode: false, // 编辑多边形
        dragMode: false, // 拖动多边形
        cutPolygon: false, // 添加一个按钮以删除多边形里面的部分内容
        removalMode: true // 清除多边形
      })
      this.map = map

      this.map.pm.setPathOptions({
        color: 'blue',
        fillColor: 'pink',
        fillOpacity: 0.4
      })
      this.map.pm.setLang('zh')

      // 创建图层
      this.map.on('pm:create', (e) => {
        this.layers.push(e.layer)
        this.map.pm.disableDraw()
      })

      // 移除图层
      this.map.on('pm:remove', (e) => {
        const index = this.getLeafletId(e)
        this.layers.splice(index, 1)
      })
    },
    drawFinish() {
      this.layers.forEach((e) => {
        const lntlngs = e._latlngs[0]
        let tmp = []
        lntlngs.forEach(item => {
          tmp.push([item.lng, item.lat].join(','))
        })
        tmp = tmp.join(';')
        this.latlngsArr.push(tmp)
      })
      this.latlngsArr = uniqueArr(this.latlngsArr)
      const postData = { cells: this.latlngsArr }
      this.saveCells(postData)
    },
    getLeafletId(e) {
      const id = e.layer._leaflet_id
      const index = this.latlngsArr.findIndex((val) => {
        return val.id === id
      })
      return index
    },
    addAwcLayer(res) {
      this.awcLayerContent = res
      this.awcLayer = this.awcLayerContent.addTo(this.map)
      this.awcLayer.setZIndex(1)
    },
    removeAwcLayer() {
      if (this.awcLayer) {
        this.map.removeLayer(this.awcLayer)
      }
    },
    createAwcLayer() {
      const data = this.awc
      var features = data.map(i => {
        return {
          type: 'Feature',
          properties: {
            value: i.awc
          },
          geometry: {
            type: 'Point',
            coordinates: [+i.lng, +i.lat]
          }
        }
      }
      )

      var points = turf.featureCollection(features)
      var interpolate_options = {
        gridType: 'points',
        property: 'value',
        units: 'degrees',
        weight: 10
      }

      var grid = turf.interpolate(points, 0.00005, interpolate_options)

      // 适当降低插值结果的精度便于显示
      grid.features.map((i) => (i.properties.value = i.properties.value.toFixed(4)))

      this.grid = grid.features.map((val) => {
        return {
          lat: val.geometry.coordinates[1],
          lng: val.geometry.coordinates[0],
          awc: val.properties.value
        }
      })

      var isobands_options = {
        zProperty: 'value',
        commonProperties: {
          'fill-opacity': 1
        },
        breaksProperties: colors.map(val => {
          return { fill: val.color }
        })
      }

      let isobands = turf.isobands(
        grid,
        colors.map(val => val.value),
        isobands_options
      )
      isobands = turf.flatten(isobands)

      const features_filter = []
      isobands.features.forEach((layer) => {
        let intersection = null
        try {
          intersection = turf.intersect(layer, this.circlePolygon)
        } catch (e) {
          layer = turf.buffer(layer, 0)
          intersection = turf.intersect(layer, this.circlePolygon)
        }
        if (intersection != null) {
          intersection.properties = layer.properties
          features_filter.push(intersection)
        }
      })
      isobands.features = features_filter

      const geoArr = isobands
      // eslint-disable-next-line no-undef
      const res = L.geoJson(geoArr, { style: this.getFlexStyle })

      this.addAwcLayer(res)
    },
    addNrctLayer(res) {
      this.nrctLayerContent = res
      this.nrctLayerContent.setZIndex(2)
      this.nrctLayer = this.nrctLayerContent.addTo(this.map)
    },
    removeNrctLayer() {
      if (this.nrctLayer) {
        this.map.removeLayer(this.nrctLayer)
      }
    },
    createNrctLayer() {
      const data = this.nrct
      var features = data.map(i => {
        return {
          type: 'Feature',
          properties: {
            value: i.gcwd
          },
          geometry: {
            type: 'Point',
            coordinates: [+i.location[0], +i.location[1]]
          }
        }
      }
      )

      var points = turf.featureCollection(features)
      var interpolate_options = {
        gridType: 'points',
        property: 'value',
        units: 'degrees',
        weight: 10
      }

      var grid = turf.interpolate(points, 0.00002, interpolate_options)

      // 适当降低插值结果的精度便于显示
      grid.features.map((i) => (i.properties.value = i.properties.value.toFixed(4)))

      this.grid = grid.features.map((val) => {
        return {
          lat: val.geometry.coordinates[1],
          lng: val.geometry.coordinates[0],
          gcwd: val.properties.value
        }
      })

      var isobands_options = {
        zProperty: 'value',
        commonProperties: {
          'fill-opacity': 1
        },
        breaksProperties: colorsGcwd.map(val => {
          return { fill: val.color }
        })
      }

      let isobands = turf.isobands(
        grid,
        colorsGcwd.map(val => val.value),
        isobands_options
      )
      isobands = turf.flatten(isobands)

      const features_filter = []
      isobands.features.forEach((layer) => {
        let intersection = null
        try {
          intersection = turf.intersect(layer, this.circlePolygon)
        } catch (e) {
          layer = turf.buffer(layer, 0)
          intersection = turf.intersect(layer, this.circlePolygon)
        }
        if (intersection != null) {
          intersection.properties = layer.properties
          features_filter.push(intersection)
        }
      })
      isobands.features = features_filter

      const geoArr = isobands
      // eslint-disable-next-line no-undef
      const res = L.geoJson(geoArr, { style: this.getFlexStyle })

      this.addNrctLayer(res)
      this.loading = false
    },
    getFlexStyle(feature) {
      return {
        weight: 1,
        opacity: 0,
        color: '#fff',
        fillOpacity: 0.6,
        fillColor: feature.properties.fill }
    }
  }
}
</script>
<style lang="scss">
.leaflet-touch .leaflet-bar a{
  width:30px;
  height:30px;
}
.button-container .leaflet-pm-actions-container{
  left:61px;
}
</style>

<style lang="scss" scoped>
.app-container{
  position:relative;
  .tools{
    position:absolute;
    top:24px;
    right:24px;
    z-index:999;
  }
  .btn-container{
      position:absolute;
      right:24px;
      bottom:24px;
      z-index:9999;
    }
}
.container {
    position:relative;
    width:100%;
    height:calc(100vh - 50px);
    .btn-container{
      position:absolute;
      right:24px;
      bottom:24px;
      z-index:9999;
    }
  }
.colors{
  position:absolute;
  top:240px;
  left:24px;
  z-index:999;
  dl{
    align-items:center;
    font-size:12px;
    dt{
      display:inline-block;
      width:60px;
      height:30px;
      line-height:30px;
      text-align:center;
      margin-right:4px;
      color:#333;
    }
  }
}
</style>
